package com.boot.persistence.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.boot.persistence.condition.QueryCondition;
import com.boot.persistence.model.BaseModel;
import com.boot.persistence.validate.group.InsertGroup;
import com.boot.persistence.validate.group.SelectGroup;
import com.boot.persistence.validate.group.UpdateGroup;
import com.boot.web.http.HttpModel;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * @author 霜寒 <1621856595@qq.com>
 * @description 通用查询 RequestMapping
 * @date 2023/2/5 15:03
 **/

@Validated(Default.class)
public interface IControllerMapping<Id extends Serializable, T extends BaseModel<Id>, Service> extends IController<Id, T, Service> {

    @Override
    @GetMapping("/id/{id}")
    @ApiOperation("通过id查找一条记录")
    @ApiImplicitParam(name = "id", value = "记录id", required = true, paramType = "path", dataTypeClass = Serializable.class)
    ResponseEntity<HttpModel<T>> selectById(@PathVariable Id id, @RequestHeader(value = "useStrict", required = false) String useStrict);

    @Override
    @PostMapping("/search")
    @ApiOperation("通过对象精确查找属性相同的一条记录")
    @ApiImplicitParam(name = "model", value = "记录样例", required = true, paramType = "body", dataTypeClass = BaseModel.class)
    ResponseEntity<HttpModel<T>> selectOne(@Validated(SelectGroup.class) @RequestBody @NotNull T model, @RequestHeader(value = "useStrict", required = false) String useStrict);

    @Override
    @PostMapping("/list/id")
    @ApiOperation(value = "通过id列表查找多条记录")
    @ApiImplicitParam(name = "list", value = "记录id列表", required = true, paramType = "body", dataTypeClass = List.class)
    ResponseEntity<HttpModel<Collection<T>>> selectByIds(@RequestBody @NotEmpty List<Id> list, @RequestHeader(value = "useStrict", required = false) String useStrict);

    @Override
    @PostMapping("/list/search")
    @ApiOperation("通过对象精确查找属性相似的多条记录")
    @ApiImplicitParam(name = "model", value = "查询条件", required = true, paramType = "body", dataTypeClass = QueryCondition.class)
    ResponseEntity<HttpModel<IPage<T>>> select(@Validated(SelectGroup.class) @RequestBody @NotNull QueryCondition<Id, T> condition);

    @Override
    @PostMapping("/list/like")
    @ApiOperation("通过对象模糊查找属性相似的多条记录")
    @ApiImplicitParam(name = "model", value = "查询条件", required = true, paramType = "body", dataTypeClass = QueryCondition.class)
    ResponseEntity<HttpModel<IPage<T>>> selectLike(@Validated(SelectGroup.class) @RequestBody @NotNull QueryCondition<Id, T> condition);

    @Override
    @GetMapping("/list")
    @ApiOperation("查询全部记录(仅实现分页和排序)")
    ResponseEntity<HttpModel<IPage<T>>> selectAll();

    @Override
    @PostMapping("/count")
    @ApiOperation("通过对象精确查找属性相同的记录个数")
    @ApiImplicitParam(name = "model", value = "记录样例", required = true, paramType = "body", dataTypeClass = BaseModel.class)
    ResponseEntity<HttpModel<Long>> selectCount(@Validated(SelectGroup.class) @RequestBody @NotNull T model);

    @Override
    @PostMapping
    @ApiOperation(value = "插入一条记录", notes = "id和某些非必须属性可为空")
    @ApiImplicitParam(name = "model", value = "记录", required = true, paramType = "body", dataTypeClass = BaseModel.class)
    ResponseEntity<HttpModel<Id>> insertRecord(@Validated(InsertGroup.class) @RequestBody @NotNull T model);

    @Override
    @PostMapping("/list")
    @ApiOperation(value = "插入多条记录", notes = "id属性可为空")
    @ApiImplicitParam(name = "list", value = "记录样例列表", required = true, paramType = "body", dataTypeClass = List.class)
    ResponseEntity<HttpModel<List<Id>>> insertRecords(@Validated(InsertGroup.class) @RequestBody @NotEmpty List<T> list);

    @Override
    @PutMapping
    @ApiOperation(value = "插入或更新一条记录", notes = "不存在记录则插入，否则修改记录")
    @ApiImplicitParam(name = "model", value = "记录", required = true, paramType = "body", dataTypeClass = BaseModel.class)
    ResponseEntity<HttpModel<Id>> saveRecord(@Validated(InsertGroup.class) @RequestBody @NotNull T model);

    @Override
    @PutMapping("/list")
    @ApiOperation(value = "插入或更新多条记录", notes = "不存在记录则插入，否则修改记录")
    @ApiImplicitParam(name = "list", value = "记录样例列表", required = true, paramType = "body", dataTypeClass = List.class)
    ResponseEntity<HttpModel<List<Id>>> saveRecords(@Validated(InsertGroup.class) @RequestBody @NotEmpty List<T> list);

    @Override
    @PatchMapping
    @ApiOperation(value = "更新一条记录", notes = "id不可为空且必须存在至少一个其它属性")
    @ApiImplicitParam(name = "model", value = "记录", required = true, paramType = "body", dataTypeClass = BaseModel.class)
    ResponseEntity<HttpModel<Void>> updateRecord(@Validated(UpdateGroup.class) @RequestBody @NotNull T model);

    @Override
    @PatchMapping("/list")
    @ApiOperation(value = "更新多条记录", notes = "id不可为空且必须存在至少一个其它属性")
    @ApiImplicitParam(name = "list", value = "记录样例列表", required = true, paramType = "body", dataTypeClass = List.class)
    ResponseEntity<HttpModel<Void>> updateRecords(@Validated(UpdateGroup.class) @RequestBody @NotEmpty List<T> list);

    @Override
    @DeleteMapping("/id/{id}")
    @ApiOperation(value = "通过id删除一条记录")
    @ApiImplicitParam(name = "id", value = "记录id", required = true, paramType = "path", dataTypeClass = Serializable.class)
    ResponseEntity<HttpModel<Void>> deleteById(@PathVariable Id id, @RequestHeader(value = "useStrict", required = false) String useStrict);

    @Override
    @DeleteMapping("/list/id")
    @ApiOperation(value = "通过id列表删除多条记录")
    @ApiImplicitParam(name = "list", value = "记录id列表", required = true, paramType = "body", dataTypeClass = List.class)
    ResponseEntity<HttpModel<Void>> deleteByIds(@RequestBody @NotEmpty List<Id> list, @RequestHeader(value = "useStrict", required = false) String useStrict);

}
